<!DOCTYPE html>
<html lang="en">

<head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8">
	<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
	
	<!-- title -->
	
	<title>
	
		SpringBean生命周期 | 
	 
	对线面试官
	</title>
	
	<!-- keywords,description -->
	 
		<meta name="description" content="Java一线大厂面试" />
	

	<!-- favicon -->
	
	<link rel="shortcut icon" href="/luffy/favicon.ico">
	


	<!-- search -->
	<script>
		var searchEngine = "https://www.baidu.com/s?wd=";
		if(typeof searchEngine == "undefined" || searchEngine == null || searchEngine == ""){
			searchEngine = "https://www.google.com/search?q=";
		}
		var homeHost = "";
		if(typeof homeHost == "undefined" || homeHost == null || homeHost == ""){
			homeHost = window.location.host;
		}
	</script>


	
<link rel="stylesheet" href="/luffy/css/main.css">

	
<link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.min.css">

	
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.17.1/build/styles/darcula.min.css">

	
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css">


	
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>

	
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>

	
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.17.1/build/highlight.min.js"></script>

	
<script src="https://cdn.jsdelivr.net/npm/jquery-pjax@2.0.1/jquery.pjax.min.js"></script>

	
<script src="/luffy/js/main.js"></script>

	
		
<script src="https://cdn.jsdelivr.net/npm/leancloud-storage/dist/av-min.js"></script>

		
<script src="https://cdn.jsdelivr.net/npm/valine@1.3.10/dist/Valine.min.js"></script>

	
	
<meta name="generator" content="Hexo 5.4.0"></head>

<body>
	<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?3efe99c287df5a1d6f0d02d187e403c1";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>

<header id="header">
    <a id="title" target="_blank" rel="noopener" href="https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzU4NzA3MTc5Mg==&action=getalbum&album_id=1657204970858872832&scene=126#wechat_redirect" class="logo">对线面试官</a>

	<ul id="menu">
		
	

	

		<li class="menu-item">
			<a href="https://gitee.com/zhongfucheng/Java3y" class="menu-item-link" target="_blank">
				【戳这里】获取更多原创干货💪💪
			</a>
		</li>
		<li class="menu-item">
			<a href="https://gitee.com/zhongfucheng/Java3y" class="menu-item-link" target="_blank">
				<i class="fa fa-github fa-2x"></i>
			</a>
		</li>
	</ul>
</header>

	
<div id="sidebar">
	<button id="sidebar-toggle" class="toggle" ><i class="fa fa-arrow-right " aria-hidden="true"></i></button>
	
	<div id="site-toc">
		<input id="search-input" class="search-input" type="search" placeholder="按回车全站搜索">
		<div id="tree">
			

			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										01-Java基础
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/01.%20%E6%B3%A8%E8%A7%A3/">
										01. 注解
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/02.%20%E6%B3%9B%E5%9E%8B/">
										02. 泛型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/03.%20JavaNIO/">
										03. JavaNIO
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/04.%20%E5%8F%8D%E5%B0%84%E5%92%8C%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/">
										04. 反射和动态代理
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										02-Java并发
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/01.%20%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%9F%BA%E7%A1%80/">
										01. 多线程基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/02.%20CAS/">
										02. CAS
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/03.%20synchronized/">
										03. synchronized
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/04.%20AQS%E5%92%8CReentrantLock/">
										04. AQS和ReentrantLock
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/05.%20%E7%BA%BF%E7%A8%8B%E6%B1%A0/">
										05. 线程池
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/06.%20ThreadLocal/">
										06. ThreadLocal
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/07.%20CountDownLatch%E5%92%8CCyclicBarrier/">
										07. CountDownLatch和CyclicBarrier
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/08.%20%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81Java%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/">
										08. 为什么需要Java内存模型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/09.%20%E6%B7%B1%E5%85%A5%E6%B5%85%E5%87%BAJava%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/">
										09. 深入浅出Java内存模型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										03-Java容器
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/03-Java%E5%AE%B9%E5%99%A8/01.%20List%E9%9B%86%E5%90%88/">
										01. List集合
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/03-Java%E5%AE%B9%E5%99%A8/02.%20Map%E9%9B%86%E5%90%88/">
										02. Map集合
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										04-Java虚拟机
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/01.%20Java%E7%BC%96%E8%AF%91%E5%88%B0%E6%89%A7%E8%A1%8C%E7%9A%84%E8%BF%87%E7%A8%8B/">
										01. Java编译到执行的过程
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/02.%20%E5%8F%8C%E4%BA%B2%E5%A7%94%E6%B4%BE%E6%9C%BA%E5%88%B6/">
										02. 双亲委派机制
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/03.%20JVM%E5%86%85%E5%AD%98%E7%BB%93%E6%9E%84/">
										03. JVM内存结构
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/04.%20%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E6%9C%BA%E5%88%B6/">
										04. 垃圾回收机制
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/05.%20CMS%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8/">
										05. CMS垃圾收集器
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/06.%20G1%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8/">
										06. G1垃圾收集器
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/24/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/07.%20JVM%E8%B0%83%E4%BC%98/">
										07. JVM调优
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										05-Spring
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/05-Spring/01.%20SpringMVC/">
										01. SpringMVC
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/05-Spring/02.%20Spring%E5%9F%BA%E7%A1%80/">
										02. Spring基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file active">
									<a href="/luffy/2021/08/19/05-Spring/03.%20SpringBean%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/">
										03. SpringBean生命周期
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										06-Redis
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/06-Redis/01.%20Redis%E5%9F%BA%E7%A1%80/">
										01. Redis基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/06-Redis/02.%20Redis%E6%8C%81%E4%B9%85%E5%8C%96/">
										02. Redis持久化
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/06-Redis/03.%20Redis%E4%B8%BB%E4%BB%8E%E6%9E%B6%E6%9E%84/">
										03. Redis主从架构
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/06-Redis/04.%20Redis%E5%88%86%E7%89%87%E9%9B%86%E7%BE%A4/">
										04. Redis分片集群
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										07-消息队列
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/07-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/01.%20Kafka%E5%9F%BA%E7%A1%80/">
										01. Kafka基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/07-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/02.%20%E4%BD%BF%E7%94%A8Kafka%E4%BC%9A%E8%80%83%E8%99%91%E4%BB%80%E4%B9%88%E9%97%AE%E9%A2%98/">
										02. 使用Kafka会考虑什么问题
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										08-MySQL
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/08-MySQL/01.%20MySQL%E7%B4%A2%E5%BC%95/">
										01. MySQL索引
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/08-MySQL/02.%20MySQL%E4%BA%8B%E5%8A%A1%E5%92%8C%E9%94%81%E6%9C%BA%E5%88%B6%E5%92%8CMVCC/">
										02. MySQL事务和锁机制和MVCC
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/08-MySQL/03.%20MySQL%E8%B0%83%E4%BC%98/">
										03. MySQL调优
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										09-项目场景类
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/09-%E9%A1%B9%E7%9B%AE%E5%9C%BA%E6%99%AF%E7%B1%BB/01.%20%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E5%8E%BB%E9%87%8D%E5%92%8C%E5%B9%82%E7%AD%89/">
										01. 如何实现去重和幂等
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/09-%E9%A1%B9%E7%9B%AE%E5%9C%BA%E6%99%AF%E7%B1%BB/02.%20%E7%B3%BB%E7%BB%9F%E9%9C%80%E6%B1%82%E5%A4%9A%E5%8F%98%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1/">
										02. 系统需求多变如何设计
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/09-%E9%A1%B9%E7%9B%AE%E5%9C%BA%E6%99%AF%E7%B1%BB/03.%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">
										03. 设计模式
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										10-计算机网络
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/25/10-%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/01.%20HTTP/">
										01. HTTP
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										11-算法
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/09/01/11-%E7%AE%97%E6%B3%95/01.%20%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95/">
										01. 排序算法
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/09/02/11-%E7%AE%97%E6%B3%95/02.%20LeetCode%20Easy/">
										02. LeetCode Easy
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/09/02/11-%E7%AE%97%E6%B3%95/02.%20LeetCode%20Medium/">
										02. LeetCode Medium
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
		</div>
	</div>
</div>

	<!-- 引入正文 -->
	<div id="content">
		<h1 id="article-title">

	03. SpringBean生命周期
</h1>
<div class="article-meta">
	
	<span>3y</span>
	<span>2021-08-19 15:39:24</span>
		<div id="article-categories">
    
		<span>Categories：</span>
            
    

    
		<span>Tags：</span>
            
    
		</div>

</div>

<div id="article-content">
	<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>今天要不来聊聊Spring对Bean的生命周期管理？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：嗯，没问题的。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：很早之前我就看过源码，但Spring源码的实现类都太长了</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：我也记不得很清楚某些实现类的名字，要不我大概来说下流程？</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：没事，你开始吧</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：首先要知道的是</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：普通Java对象和Spring所管理的Bean实例化的过程是有些区别的</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：在普通Java环境下创建对象简要的步骤可以分为：</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：1):java源码被编译为被编译为class文件</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：2):等到类需要被初始化时（比如说new、反射等）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：3):class文件被虚拟机通过类加载器加载到JVM</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：4):初始化对象供我们使用</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：简单来说，可以理解为它是用Class对象作为「模板」进而创建出具体的实例</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtytmd768tj60wa0a0t9702.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：而Spring所管理的Bean不同的是，除了Class对象之外，还会使用BeanDefinition的实例来描述对象的信息</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：比如说，我们可以在Spring所管理的Bean有一系列的描述：@Scope、@Lazy、@DependsOn等等</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：可以理解为：Class只描述了类的信息，而BeanDefinition描述了对象的信息</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：嗯，这我大致了解你的意思了。</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：你就是想告诉我，<strong>Spring有BeanDefinition来存储着我们日常给Spring Bean定义的元数据（@Scope、@Lazy、@DependsOn等等），对吧？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：不愧是你</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：赶紧的，继续吧</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtytnenuorj60fe064q3b02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：Spring在启动的时候需要「扫描」在XML/注解/JavaConfig 中需要被Spring管理的Bean信息</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：随后，会将这些信息封装成BeanDefinition，最后会把这些信息放到一个beanDefinitionMap中</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：我记得这个Map的key应该是beanName，value则是BeanDefinition对象</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：到这里其实就是把定义的元数据加载起来，目前真实对象还没实例化</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtyto3x2adj60ga0e6t9i02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：接着会遍历这个beanDefinitionMap，执行BeanFactoryPostProcessor这个Bean工厂后置处理器的逻辑</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：比如说，我们平时定义的占位符信息，就是通过BeanFactoryPostProcessor的子类PropertyPlaceholderConfigurer进行注入进去</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：当然了，这里我们也可以自定义BeanFactoryPostProcessor来对我们定义好的Bean元数据进行获取或者修改</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：只是一般我们不会这样干，实际上也很有少的使用场景</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtytott4ofj61380680tz02.jpg"></p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：嗯….</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：BeanFactoryPostProcessor后置处理器执行完了以后，就到了实例化对象啦</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：在Spring里边是通过反射来实现的，一般情况下会通过反射选择合适的构造器来把对象实例化</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：但这里把对象实例化，只是把对象给创建出来，而对象具体的属性是还没注入的。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：比如我的对象是UserService，而UserService对象依赖着SendService对象，这时候的SendService还是null的</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：所以，下一步就是把对象的相关属性给注入（：</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtyttnw37hj60kk06mgln02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：相关属性注入完之后，往下接着就是初始化的工作了</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：首先判断该Bean是否实现了Aware相关的接口，如果存在则填充相关的资源</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：比如我这边在项目用到的：我希望通过代码程序的方式去获取指定的Spring Bean</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：我们这边会抽取成一个工具类，去实现ApplicationContextAware接口，来获取ApplicationContext对象进而获取Spring  Bean</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtytupwljcj60r806gglz02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：Aware相关的接口处理完之后，就会到BeanPostProcessor后置处理器啦</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：BeanPostProcessor后置处理器有两个方法，一个是before，一个是after（那肯定是before先执行、after后执行）</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtytvcungvj60qe05274m02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：这个BeanPostProcessor后置处理器是AOP实现的关键（关键子类AnnotationAwareAspectJAutoProxyCreator）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：所以，执行完Aware相关的接口就会执行BeanPostProcessor相关子类的before方法</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：BeanPostProcessor相关子类的before方法执行完，则执行init相关的方法，比如说@PostConstruct、实现了InitializingBean接口、定义的init-method方法</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：当时我还去官网去看他们的被调用「执行顺序」分别是：@PostConstruct、实现了InitializingBean接口以及init-method方法</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：这些都是Spring给我们的「扩展」，像@PostConstruct我就经常用到</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtyv762atgj60u00fq74w02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：比如说：对象实例化后，我要做些初始化的相关工作或者就启个线程去Kafka拉取数据</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：等到init方法执行完之后，就会执行BeanPostProcessor的after方法</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：基本重要的流程已经走完了，我们就可以获取到对象去使用了</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：销毁的时候就看有没有配置相关的destroy方法，执行就完事了</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：嗯，了解，但我的观众好像不太满意，总感觉少了些什么。</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>你看过Spring是怎么解决循环依赖的吗？</strong></p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>如果现在有个A对象，它的属性是B对象，而B对象的属性也是A对象</strong></p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>说白了就是A依赖B，而B又依赖A，Spring是怎么做的？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：嗯，这块我也是看过的，其实也是在Spring的生命周期里面嘛</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：从上面我们可以知道，对象属性的注入在对象实例化之后的嘛。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：它的大致过程是这样的：</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：首先A对象实例化，然后对属性进行注入，发现依赖B对象</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：B对象此时还没创建出来，所以转头去实例化B对象</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：B对象实例化之后，发现需要依赖A对象，那A对象已经实例化了嘛，所以B对象最终能完成创建</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：B对象返回到A对象的属性注入的方法上，A对象最终完成创建</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：上面就是大致的过程；</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>听起来你还会原理哦？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：Absolutely</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：至于原理，其实就是用到了三级的缓存</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：所谓的三级缓存其实就是三个Map…首先明确一定，我对这里的三级缓存定义是这样的：</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：singletonObjects（一级，日常实际获取Bean的地方）；</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：earlySingletonObjects（二级，还没进行属性注入，由三级缓存放进来）；</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：singletonFactories（三级，Value是一个对象工厂）；</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtyval7yubj60va0g8gmb02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：再回到刚才讲述的过程中，A对象实例化之后，属性注入之前，其实会把A对象放入三级缓存中</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：key是BeanName，Value是ObjectFactory</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：等到A对象属性注入时，发现依赖B，又去实例化B时</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：B属性注入需要去获取A对象，这里就是从三级缓存里拿出ObjectFactory，从ObjectFactory得到对应的Bean（就是对象A）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：把三级缓存的A记录给干掉，然后放到二级缓存中</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：显然，二级缓存存储的key是BeanName，value就是Bean（这里的Bean还没做完属性注入相关的工作）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：等到完全初始化之后，就会把二级缓存给remove掉，塞到一级缓存中</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：我们自己去getBean的时候，实际上拿到的是一级缓存的</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：大致的过程就是这样</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>那我想问一下，为什么是三级缓存？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：首先从第三级缓存说起（就是key是BeanName，Value为ObjectFactory）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：我们的对象是单例的，有可能A对象依赖的B对象是有AOP的（B对象需要代理）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：假设没有第三级缓存，只有第二级缓存（Value存对象，而不是工厂对象）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：那如果有AOP的情况下，岂不是在存入第二级缓存之前都需要先去做AOP代理？这不合适嘛</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：这里肯定是需要考虑代理的情况的，比如A对象是一个被AOP增量的对象，B依赖A时，得到的A肯定是代理对象的</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：所以，三级缓存的Value是ObjectFactory，可以从里边拿到代理对象</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：而二级缓存存在的必要就是为了性能，从三级缓存的工厂里创建出对象，再扔到二级缓存（这样就不用每次都要从工厂里拿）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：应该很好懂吧？</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtyvbmz9z2j60ri05s0t102.jpg"></p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：确实（：</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：我稍微总结一下今天的内容吧</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：怕你的观众说不满意，那我就没有赞了，没有赞我就很难受</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：首先是Spring Bean的生命周期过程，Spring使用BeanDefinition来装载着我们给Bean定义的元数据</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：实例化Bean的时候实际上就是遍历BeanDefinitionMap</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：Spring的Bean实例化和属性赋值是分开两步来做的</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：在Spring Bean的生命周期，Spring预留了很多的hook给我们去扩展</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：1）：Bean实例化之前有BeanFactoryPostProcessor</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：2）：Bean实例化之后，初始化时，有相关的Aware接口供我们去拿到Context相关信息</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：3）：环绕着初始化阶段，有BeanPostProcessor（AOP的关键）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：4）：在初始化阶段，有各种的init方法供我们去自定义</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：而循环依赖的解决主要通过三级的缓存</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：在实例化后，会把自己扔到三级缓存（此时的key是BeanName，Value是ObjectFactory）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：在注入属性时，发现需要依赖B，也会走B的实例化过程，B属性注入依赖A，从三级缓存找到A</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：删掉三级缓存，放到二级缓存</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>嗯，你要不后面放点关键的源码吧</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：这你倒是提醒我了，确实有必要</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：这要是能听懂，是真的看过源码才行（：还好我看过</p>
<p>关键源码方法（强烈建议自己去撸一遍）</p>
<ul>
<li><code>org.springframework.context.support.AbstractApplicationContext#refresh</code>(入口)</li>
<li><code>org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization</code>(初始化单例对象入口)</li>
<li><code>org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons</code>(初始化单例对象入口)</li>
<li><code>org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)</code>（万恶之源，获取并创建Bean的入口）</li>
<li><code>org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean</code>（实际的获取并创建Bean的实现）</li>
<li><code>org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)</code>（从缓存中尝试获取）</li>
<li><code>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])</code>（实例化Bean）</li>
<li><code>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean</code>（实例化Bean具体实现）</li>
<li><code>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance</code>（具体实例化过程）</li>
<li><code>org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory</code>（将实例化后的Bean添加到三级缓存）</li>
<li><code>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean</code>（实例化后属性注入）</li>
<li><code>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)</code>（初始化入口）</li>
</ul>
<p><img src="https://tva1.sinaimg.cn/large/008eGmZEly1gne0dib6jwj30u10g50xh.jpg"></p>
<p><img src="https://tva1.sinaimg.cn/large/008eGmZEly1gne0ey29w2j30tt0cqtdy.jpg"></p>
<p><img src="https://tva1.sinaimg.cn/large/008eGmZEly1gne0b6gfbpj30vd0u0wje.jpg" alt="来源：https://www.jianshu.com/p/6c359768b1dc"></p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtm56nkinlj61400h03zz02.jpg"></p>
<p><span align="center">第一时间获取<span style="color:#000080"><strong>BATJTMD一线互联网大厂</strong></span>最新的面试资料以及内推机会关注公众号<span style="color:#ab4642"><strong>「对线<span style="color:#ab4642"><strong>面试官</strong></span>」</strong></span></p>
<img align="center" src='https://tva1.sinaimg.cn/large/008i3skNgy1gtlvty8zo5j60u00u0q5602.jpg' width=300px height=300px />


</div>


    <div class="post-guide">
        <div class="item left">
            
              <a href="/luffy/2021/08/19/06-Redis/01.%20Redis%E5%9F%BA%E7%A1%80/">
                  <i class="fa fa-angle-left" aria-hidden="true"></i>
                  01. Redis基础
              </a>
            
        </div>
        <div class="item right">
            
              <a href="/luffy/2021/08/19/05-Spring/02.%20Spring%E5%9F%BA%E7%A1%80/">
                02. Spring基础
                <i class="fa fa-angle-right" aria-hidden="true"></i>
              </a>
            
        </div>
    </div>




<script>
	
	
</script>
	</div>
	<button id="totop-toggle" class="toggle"><i class="fa fa-angle-double-up" aria-hidden="true"></i></button>
</body>
</html>
